using System;
using System.Collections;
using System.Text;

namespace Qiang.Topology.Geometries
{
    /// <summary>  
    /// Basic implementation of <c>LinearRing</c>.
    /// The first and last point in the coordinate sequence must be equal.
    /// Either orientation of the ring is allowed.
    /// A valid ring must not self-intersect.
    /// </summary>    
    public class LinearRing : LineString,ILinearRing
    {
        /// <summary>
        /// Constructs a <c>LinearRing</c> with the given points.
        /// </summary>
        /// <param name="points">
        /// Points forming a closed and simple linestring, or
        /// <c>null</c> or an empty array to create the empty point.
        /// This array must not contain <c>null</c> elements.
        /// </param>
        /// <param name="precisionModel">
        /// The specification of the grid of allowable points
        /// for this <c>LinearRing</c>.
        /// </param>
        /// <param name="SRID">
        /// The ID of the Spatial Reference System used by this
        /// <c>LinearRing</c>.
        /// </param>
        /// <deprecated>
        /// Use GeometryFactory instead.
        /// </deprecated>
        [Obsolete("Use GeometryFactory instead")]
        public LinearRing(Coordinate[] points, PrecisionModel precisionModel, int SRID) 
            : this(DefaultCoordinateSequenceFactory.Instance.Create(points == null ? new Coordinate[]{} : points), 
            new GeometryFactory(precisionModel, SRID, DefaultCoordinateSequenceFactory.Instance)) { }

        /// <summary>
        /// Constructs a <c>LinearRing</c> with the given points.
        /// </summary>
        /// <param name="points">
        /// Points forming a closed and simple linestring, or
        /// <c>null</c> or an empty array to create the empty point.
        /// This array must not contain <c>null</c> elements.
        /// </param>
        public LinearRing(ICoordinateSequence points, GeometryFactory factory) : base(points, factory)
        {            
            ValidateConstruction();
        }


        public LinearRing(Coordinate[] points)
            : this(new DefaultCoordinateSequence(points), DefaultGeometryFactory)
        { }


        private void ValidateConstruction() 
        {
	        if (!IsEmpty && !base.IsClosed) 
                throw new ArgumentException("points must form a closed linestring");            
            if (CoordinateSequence.Count >= 1 && CoordinateSequence.Count <= 3) 
                throw new ArgumentException("Number of points must be 0 or >3");            
        }

        public override bool IsSimple
        {
            get
            {
                return true;
            }
        }

        [Obsolete("Use reflection! GetType().FullName")]
        public override string GeometryType
        {
            get
            {
                return "LinearRing";
            }
        }

        public override bool IsClosed
        {
            get
            {
                return true;
            }
        }
    }
}
